#include "ReadClientRequestTask.hpp"
#include "util/Log.hpp"
#include "util/StringUtils.hpp"
#include "proxy/CacheTask.hpp"
#include "proxy/CacheController.hpp"
#include "pthread/ScopedLock.hpp"
ReadClientRequest::ReadClientRequest(int fileDescriptor) :
		Task(fileDescriptor), written(0), cacheEntry(0) {

}

void ReadClientRequest::onInit(Context & context) {
	context.enableRead();
}

void ReadClientRequest::onRead(Context & context) {
	checkSocket();
	const std::string & buffer = read(1);
	if (buffer.length() > 0) {
		if (buffer == "\n") {
			//Log::v("[ReadClientRequest] On new line [" + data + "]");
			bool result = parser.putLine(data);
			if (!result) {
				request = parser.getHttpRequest();
				Log::v(request.toString());
				Log::v(
						"[ClientTask] ["
								+ StringUtils::toString(getFileDiscriptor())
								+ "] " + request.getHttpQuery());

				context.disableRead();



				CacheController & controller = CacheController::getInstance();
				cacheEntry = controller.get(context, request);
				cacheEntry->registerTask();
				context.enableWrite();
			}
			data.clear();

		} else {
			data += buffer;
		}

	} else {
		context.unregister();
	}

}

void ReadClientRequest::onWrite(Context & context) {
	checkSocket();
	ScopedLock lock(*cacheEntry);
//	Log::v(
//			"[ClientTask] [" + StringUtils::toString(getFileDiscriptor())
//					+ "] onWrite() " + StringUtils::toString(written) + " of "
//					+ StringUtils::toString(cacheEntry->getSize()) + " "
//					+ parser.getHttpRequest().getHttpQuery());
	if (written < cacheEntry->getSize()) {

		written += write(cacheEntry->getData(), written);
		if (written == cacheEntry->getSize()) {
			context.disableWrite();
			context.unregister();
			cacheEntry->unregisterTask();
		}
	} else {
		context.disableWrite();
		context.unregister();
		cacheEntry->unregisterTask();
	}
}

std::string ReadClientRequest::toString() {
	if(cacheEntry != NULL)
	return "[ClientTask] " + StringUtils::toString(written) + " of "
			+ StringUtils::toString(cacheEntry->getSize()) + " "
			+ Task::toString() + " " + request.getHttpQuery();
	else {
		return "[ClientTask] unknown of unknown"
				+ Task::toString() + " " + request.getHttpQuery();
	}
}
